做了這麼多準備工夫,今天終於可以開始來寫creators.py
的幾個function
。一旦有了各種creator
後,我們的code就會精簡許多,減少很多boilerplate的typing。
creator function
最終都需透過base.CreateEntity
來建立Entity
,所以pattern
都很相似,目標是找出各function
的deck
,element_type
及fields
。
deck
使用我們一貫的short circuit技巧,如果沒指定則設為constants.LSDYNA
。element_type
則引用schemas.py
中的LSDYNAType.NODE
。
最後將給定的fields
與上述的deck
及element_type
一併置入base.CreateEntity
,並return
。
# creators.py
def create_node(fields, deck=None):
deck = deck or constants.LSDYNA
type_ = LSDYNAType.NODE
return base.CreateEntity(deck, type_, fields)
此處element_type
我們使用LSDYNAType.SHELL
,ANSA會自動認為我們想建立一個QUAD4 element
,在我們當前的使用情況不會有問題。我們會在之後使用base.ImportV1
時,試著修正這個問題。
# creators.py
def create_shell(fields, deck=None):
deck = deck or constants.LSDYNA
type_ = LSDYNAType.SHELL
return base.CreateEntity(deck, type_, fields)
create_mat
的步驟稍微多一點,我們慢慢來看。
element_type
,我們使用short circuit的技巧,將其預設為常用的MAT1
材料卡。fields
,我們這邊取名叫vals
,如果沒有給定的話,則設為一個空的dict
。name
的話,使用我們先前建立的get_one_material_name
來自動建立材料名。force_val
的dict
, 將DEFINED
設為YES
,這樣我們就不用在輸出的時候,再調整每個材料的visibility
。name
,vals
,force_vals
組合成fields
。此處需留意組合的順序,由於name
其實是可以放在vals
內由使用者給定,所以我們將vals
放在第二位。如果有給定的話,則會使用給定的名字蓋過第一位的name
。另外,由於我們想強迫所有材料都是預設會輸出的,所以要擺在最後一位,這樣即使使用者在vals
中指定DEFINE
為NO
,也會被第三位的force_vals
蓋過去。deck
、element_type
及fields
一併置入base.CreateEntity
,並return
。# creators.py
def create_mat(mat_type=None, name=None, vals=None, deck=None):
deck = deck or constants.LSDYNA
type_ = mat_type or MatType.MAT1_MAT_ELASTIC
name = name or get_one_material_name()
vals = vals or {}
force_vals = {'DEFINED': 'YES'}
fields = {**{'Name': name},
**vals,
**force_vals}
return base.CreateEntity(deck, type_, fields)
create_sec
的邏輯與create_mat
類似,只是使用create_sec
可以同時建立material
及property
。
值得一提的是,這邊我們使用get_mat_prop_id
來取得一個id
,可以同時給material
及property
使用。
# creators.py
def create_sec(sec_type=None,
mat_type=None,
name=None,
vals=None,
matvals=None,
deck=None):
deck = deck or constants.LSDYNA
type_ = sec_type or SecType.SECTION_SHELL
name = name or get_one_section_name()
vals = vals or {}
matvals = matvals or {}
used_mat_prop_id = get_mat_prop_id()
matvals = {**{'MID': used_mat_prop_id}, **matvals}
mat = create_mat(mat_type=mat_type, vals=matvals)
force_vals = {'DEFINED': 'YES'}
fields = {**{
'Name': name,
'PID': used_mat_prop_id,
'MID': used_mat_prop_id},
**vals,
**force_vals}
return base.CreateEntity(deck, type_, fields)
create_set
的前半部建立了一個空的set Entity
,如果有指定想放入set
內的entities
的話,我們使用base.AddToSet
將其加入,最後回傳這個set Entity
。
# creators.py
def create_set(entities=None, name=None, deck=None):
deck = deck or constants.LSDYNA
type_ = LSDYNAType.SET
name = name or get_one_set_name()
fields = {'Name': name}
set_entity = base.CreateEntity(deck, type_, fields)
if entities is not None:
base.AddToSet(set_entity, entities)
return set_entity
create_contact
的contact_type
預設為常用的AUTOMATIC_SURFACE_TO_SURFACE
。至於sstyp
及mstyp
則可透過schemas
中的ContactType
來調整。
# creators.py
def create_contact(ssid: int,
msid: int,
sstyp: str,
mstyp: str,
contact_type=None,
name=None,
vals=None,
deck=None):
deck = deck or constants.LSDYNA
type_ = LSDYNAType.CONTACT
contact_type = contact_type or ContactTypeName.AUTOMATIC_SURFACE_TO_SURFACE.value
name = name or get_one_contact_name()
vals = vals or {}
fields = {**{'Name': name,
'TYPE': contact_type,
'SSID': ssid,
'MSID': msid,
'SSTYP': sstyp,
'MSTYP': mstyp},
**vals}
return base.CreateEntity(deck, type_, fields)
相關creator function
代換後的結果,請參考本日的box_drop.py
。